#include "identifierstring.h"
#include "../../semantics/method.h"
#include "../../semantics/error.h"
#include "../../semantics/visitordata.h"
#include "../../code/opcodes.h"

bool IdentifierNode::isIdentifier()
{
	return true;
}

bool IdentifierNode::isLValue(ParentData * data)
{
	return this->data()!="PRECURSOR" && this->data()!="CURRENT" && this->data()!="VOID";
}
IdentifierNode::~IdentifierNode()
{
	if (this->isOwningData())
		delete this->m_string_data;
}

void IdentifierNode::write(GraphStream * s)
{
	this->accept(s);
	fprintf(s->stream,"\tnode_%d [label=\"(%d,%d)\\nIDENTIFIER(%s)\" shape=\"rectangle\"]\n",this->number(),m_line,m_pos,this->data().c_str());
}

std::string IdentifierNode::getType(ParentData * data)
{
	if (this->data()=="VOID")
	{
		return "VOID";
	}

	int index=data->CurrentMethod->findLocalVar(this->data());

	if (index!=-1)
	{
		return data->CurrentMethod->getArgByIndex(index,true)->fullName();
	}
	else
	{
		index=data->CurrentMethod->findFormalArg(this->data());
		if (index!=-1)
		{
			return data->CurrentMethod->getArgByIndex(index,false)->fullName();
		}
	}
	data->Classes->add(new LocalVariableNotFound(this));
	return this->AbstractNode::getType(data);
}

bool IdentifierNode::checkLogic(ParentData * data)
{
	data->Classes->add(new ExpressionMakesNoSense(this));
	return false;
}

void IdentifierNode::fillConstant(ParentData * data)
{
	m_index=data->CurrentMethod->getLocalNumberByName(this->data());;
}

void IdentifierNode::produceCode(ParentData * data)
{
	JBFile * file=data->currentFile();
	file->write(ALOAD);
	file->write((unsigned char)m_index);
}